package com.xhwl.logistics.strategy.impl;

import com.xhwl.common.dto.cent.vehicle.feign.CreateBiVehicleAccessRecordHourFeignDTO;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.logistics.bo.VehicleAccessRecordSecondBO;
import com.xhwl.logistics.bo.VehicleCarportBO;
import com.xhwl.logistics.bo.VehicleCarportNanTouBO;
import com.xhwl.logistics.bo.VehicleParkingLotSecondBO;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.bo.input.QueryVehicleAccessRecordRealtimeBO;
import com.xhwl.logistics.bo.input.QueryVehicleCarportBO;
import com.xhwl.logistics.bo.manipulate.VehicleSyncBO;
import com.xhwl.logistics.constant.VehicleConstant;
import com.xhwl.logistics.converter.mapstruct.CentBiConverter;
import com.xhwl.logistics.converter.mapstruct.VehicleAccessRecordRealtimeConverter;
import com.xhwl.logistics.converter.mapstruct.VehicleCarportConverter;
import com.xhwl.logistics.dto.http.AccessRecordNanTouDTO;
import com.xhwl.logistics.dto.http.AccessRecordStatisticsNanTouDTO;
import com.xhwl.logistics.dto.http.CarportNanTouDTO;
import com.xhwl.logistics.dto.http.query.QueryAccessRecordNanTouDTO;
import com.xhwl.logistics.dto.http.query.QueryAccessRecordStatisticsNanTouDTO;
import com.xhwl.logistics.dto.http.query.QueryCarportNanTouDTO;
import com.xhwl.logistics.service.IVehicleParkingLotService;
import com.xhwl.logistics.service.cent.IBIVehicleService;
import com.xhwl.logistics.service.impl.http.NanTouHttpServiceImpl;
import com.xhwl.logistics.strategy.IVehicleParkingLotHandler;
import com.xhwl.logistics.util.AboutDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
//@Service
public class VehicleParkingLotNanTouHandlerImpl implements IVehicleParkingLotHandler {

    @Autowired
    private NanTouHttpServiceImpl nanTouHttpService;

    @Autowired
    private IVehicleParkingLotService vehicleParkingLotService;

    @Autowired
    private IBIVehicleService biVehicleService;

    @Autowired
    private VehicleCarportConverter vehicleCarportConverter;

    @Autowired
    private CentBiConverter centBiConverter;

    @Autowired
    private VehicleParkingLotNanTouSyncHandlerImpl vehicleParkingLotNanTouSyncHandler;

    @Autowired
    private VehicleAccessRecordRealtimeConverter vehicleAccessRecordRealtimeConverter;

    @Override
    public void sync(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleSyncBO vehicleSyncBO) {
        log.info("Nan tou Sync!");
        log.info("vehicleIntegratedConfigBO: " + vehicleIntegratedConfigBO);
        vehicleParkingLotNanTouSyncHandler.syncCarList(vehicleIntegratedConfigBO,vehicleSyncBO);
    }

    @Override
    public VehicleCarportBO queryCarport(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, QueryVehicleCarportBO queryVehicleCarportBO) {

        List<VehicleParkingLotSecondBO> vehicleParkingLotSecondBOList = vehicleParkingLotService.queryParkingLots(queryVehicleCarportBO.getProjectId(), queryVehicleCarportBO.getParkingLotName());
        if (vehicleParkingLotSecondBOList.isEmpty()) {
            throw new BusinessException("通过项目id和车场名称找不到车场");
        }

        List<VehicleCarportNanTouBO> vehicleCarportNanTouBOList = vehicleParkingLotSecondBOList.stream()
                .map(vehicleParkingLotSecondBO -> {
                    CarportNanTouDTO carportNanTouDTO = nanTouHttpService.queryCarport(vehicleIntegratedConfigBO, new QueryCarportNanTouDTO(vehicleParkingLotSecondBO.getParkId()));
                    return vehicleCarportConverter.carportNanTouDTO2VehicleCarportBO(carportNanTouDTO);
                })
                .collect(Collectors.toList());

        return vehicleCarportNanTouBOList.stream()
                .reduce(new VehicleCarportNanTouBO(0, 0, 0),
                        (x, y) -> new VehicleCarportNanTouBO(Integer.sum(x.getTotalNumber(),y.getTotalNumber()),
                                Integer.sum(x.getFreeNumber(), y.getFreeNumber()),
                                Integer.sum(x.getTemporaryCardNumber(), y.getTemporaryCardNumber()),
                                Integer.sum(x.getMonthCardANumber(), y.getMonthCardANumber()),
                                Integer.sum(x.getMonthCardBNumber(), y.getMonthCardBNumber())));
    }

    @Override
    public List<VehicleAccessRecordSecondBO> queryAccessRecordRealtime(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, QueryVehicleAccessRecordRealtimeBO queryVehicleAccessRecordRealtimeBO) {
        List<VehicleParkingLotSecondBO> vehicleParkingLotSecondBOList = vehicleParkingLotService.queryParkingLots(queryVehicleAccessRecordRealtimeBO.getProjectId(), queryVehicleAccessRecordRealtimeBO.getParkingLotName());
        if (vehicleParkingLotSecondBOList.isEmpty()) {
            throw new BusinessException("通过项目id和车场名称找不到车场");
        }

        return vehicleParkingLotSecondBOList.stream()
                .flatMap(vehicleParkingLotSecondBO -> {
                    List<AccessRecordNanTouDTO> accessRecordNanTouDTOList = nanTouHttpService.queryAccessRecords(vehicleIntegratedConfigBO,
                            new QueryAccessRecordNanTouDTO(vehicleParkingLotSecondBO.getParkId(),
                                    AboutDateUtil.dateToString(queryVehicleAccessRecordRealtimeBO.getStartTime()),
                                    AboutDateUtil.dateToString(queryVehicleAccessRecordRealtimeBO.getEndTime())
                            )
                    );
                    return vehicleAccessRecordRealtimeConverter.accessRecordNanTouDTOList2VehicleAccessRecordSecondBOList(accessRecordNanTouDTOList).stream();
                })
                .collect(Collectors.toList());
    }

    @Async("threadPoolTaskExecutorForSchedule")
    @Override
    public void statisticsToBi(VehicleIntegratedConfigBO vehicleIntegratedConfigBO) {
        Date processDate = new Date();
        Integer projectId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId();

        List<VehicleParkingLotSecondBO> vehicleParkingLotSecondBOList = vehicleParkingLotService.queryParkingLots(projectId, null);
        vehicleParkingLotSecondBOList.forEach(vehicleParkingLotSecondBO -> {
            String parkId = vehicleParkingLotSecondBO.getParkId();
            String parkingLotName = vehicleParkingLotSecondBO.getParkingLotName();

            Date ingestionDate = AboutDateUtil.dateMinusHour(AboutDateUtil.theSameDayHourOfDate(processDate, VehicleConstant.vehicleTimeZone), 1);
            AccessRecordStatisticsNanTouDTO accessRecordStatisticsNanTouDTO = nanTouHttpService.queryAccessRecordStatistics(vehicleIntegratedConfigBO, new QueryAccessRecordStatisticsNanTouDTO(parkId));

            CreateBiVehicleAccessRecordHourFeignDTO createBiVehicleAccessRecordHourFeignDTO = centBiConverter.toCreateBiVehicleAccessRecordHourFeignDTO(
                    projectId, parkingLotName,
                    accessRecordStatisticsNanTouDTO.getTotal(), accessRecordStatisticsNanTouDTO.getIn(), accessRecordStatisticsNanTouDTO.getOut(),
                    processDate, ingestionDate);
            biVehicleService.addDwsAccessRecordForHour(createBiVehicleAccessRecordHourFeignDTO);
        });
    }
}
